<template>
  <div>
    <a-menu v-if="menus.length > 0" mode="inline" theme="dark" :inline-collapsed="collapsed" :inline-indent="12" v-model="selectedKeys" @click="onClick" :open-keys.sync="openKeys">
      <template v-for="item in menus">
        <sub-menu v-if="item.children" :key="item.key" :menu-info="item" />
        <a-menu-item v-else :key="item.key" :value="item.name" :disabled="!item.name">
          <a-icon :type="item.icon || 'ant-design'" /><span class="sjht-select-none">{{ item.title }}</span>
        </a-menu-item>
      </template>
    </a-menu>

    <div v-else class="no-auth">
      <a-icon type="lock" :style="{ fontSize: '48px' }" />
      <p>无操作权限</p>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { Menu } from 'ant-design-vue'
import { random } from '../../../utils/common'
const SubMenu = {
  template: `
      <a-sub-menu v-bind="$props" v-on="$listeners">
        <template #title>
          <a-icon v-if="menuInfo.icon" :type="menuInfo.icon" /><span class="sjht-select-none">{{ menuInfo.title }}</span>
        </template>
        <template v-for="item in menuInfo.children">
          <sub-menu v-if="item.children" :key="item.key" :menu-info="item" />
          <a-menu-item v-else :key="item.key" :value="item.name" :disabled="!item.name">
            <a-icon :type="item.icon || 'ant-design'" /><span class="sjht-select-none">{{ item.title }}</span>
          </a-menu-item>
        </template>
      </a-sub-menu>
    `,
  name: 'SubMenu',
  components: {
    [Menu.Item.name]: Menu.Item,
    [Menu.SubMenu.name]: Menu.SubMenu
  },
  isSubMenu: true, // must add isSubMenu: true
  props: {
    ...Menu.SubMenu.props, // Cannot overlap with properties within Menu.SubMenu.props
    menuInfo: {
      type: Object,
      default: () => ({})
    }
  }
}
let cacheOpenKeys = [] //缓存菜单打开keys
export default {
  name: 'SjhtSiderMenu', //左侧菜单
  components: {
    [Menu.name]: Menu,
    [Menu.Item.name]: Menu.Item,
    SubMenu
  },
  props: {
    // 收起状态
    collapsed: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      openKeys: [],
      selectedKeys: []
    }
  },
  created() {
    this.selectedOrOpenKeys(this.$route.name)
  },
  computed: {
    ...mapGetters({ ConfigMenu: 'menus' }),
    menus: function () {
      // 递归函数
      const recursion = function (arr, key) {
        const list = []
        arr.forEach((item, index) => {
          const _key = key.concat([index])
          const obj = {
            key: _key.join('-'),
            title: item.title
          }
          if (item.icon) obj['icon'] = item.icon
          if (item.name) obj['name'] = item.name
          if (item.children?.length > 0) {
            Object.assign(obj, { children: recursion(item.children, _key) })
          }
          list.push(obj)
        })
        return list
      }
      return recursion(this.ConfigMenu, [])
    }
  },
  watch: {
    //监听路由变化
    $route(to) {
      if (!to.query?.r) this.selectedOrOpenKeys(to.name)
    },
    //监听收起状态-要处理一下openKeys属性，收起后先缓存起来再把openKeys清空，不然会出现异常
    collapsed(val) {
      if (val) {
        cacheOpenKeys = this.openKeys
        this.openKeys = []
      } else this.openKeys = cacheOpenKeys
    }
  },
  methods: {
    // 点击导航 跳转路由
    onClick({ item, key }) {
      if (!this.selectedKeys.includes(key) && item.value !== this.$route.name) {
        this.$router.push({ name: item.value, query: { r: random() } }) //r:标识是菜单点击导航
      }
    },
    selectedOrOpenKeys(name) {
      function recursion(menus, keys) {
        for (let i = 0; i < menus.length; i++) {
          const item = menus[i]
          if (item?.name === name) {
            return {
              openKeys: keys,
              selectedKeys: [item.key]
            }
          } else if (item.children?.length > 0) {
            const res = recursion(item.children, keys.concat([item.key]))
            if (res) return res
          }
        }
      }
      const res = recursion(this.menus, [])
      if (res) {
        if (this.selectedKeys[0] != res.selectedKeys[0]) {
          const arr = this.openKeys.concat(res.openKeys) //合并数组
          this.openKeys = Array.from(new Set(arr)) //通过set集合去重
          this.selectedKeys = res.selectedKeys
        }
      } else if (this.selectedKeys.length > 0) this.selectedKeys = [] //没有匹配到菜单就把选中清空
    }
  }
}
</script>

<style lang="less" scoped>
.no-auth {
  width: 200px;
  margin-top: 40px;
  text-align: center;
  color: rgba(255, 255, 255, 0.3);
  user-select: none;
}
</style>